#pragma once

#include "Singleton.h"
#include "FrameWorker.h"
#include "Game/ServerService.h"
#include "rank/RBTreeRank.h"

class RankMgr : public FrameWorker, public AsyncTaskOwner,
	public IServerService, public Singleton<RankMgr>
{
public:
	THREAD_RUNTIME(RankMgr)

	RankMgr();
	virtual ~RankMgr();

	virtual void Update(uint64 diffTime);

	void ClearAllPlayerRankData();
	void ClearAllGuildRankData();

	GErrorCode HandleNewPlayer(INetPacket& pck);
	GErrorCode HandleUpdatePlayer(INetPacket& pck);
	GErrorCode HandleRemovePlayer(INetPacket& pck);

	GErrorCode HandleNewGuild(INetPacket& pck);
	GErrorCode HandleUpdateGuild(INetPacket& pck);
	GErrorCode HandleRemoveGuild(INetPacket& pck);

	GErrorCode HandleGetPlayerRankList(Coroutine::YieldContext& ctx,
		uint32 playerId, uint8 subType, uint32 startIndex, uint32 getCountMax);
	GErrorCode HandleGetGuildRankList(Coroutine::YieldContext& ctx,
		uint32 playerId, uint32 guildId, uint8 subType, uint32 startIndex, uint32 getCountMax);

	GErrorCode HandlePackGuildRankValue(
		INetPacket& pck, uint8 subType, INetPacket& source);
	GErrorCode HandlePackGuildRankIdList(
		INetPacket& pck, uint8 subType, uint32 startIndex, uint32 getCountMax);

private:
	RankData4Player* GetRankData4Player(uint32 playerId) const;
	static void PackRankData4Player(INetPacket& pck, const RankData4Player* pRankData, uint8 subType);

	RankData4Guild* GetRankData4Guild(uint32 playerId) const;
	static void PackRankData4Guild(INetPacket& pck, const RankData4Guild* pRankData, uint8 subType);

	virtual int HandleClientPacket(uint32 uid, INetPacket& pck);
	virtual int HandleServerPacket(INetPacket& pck);

	std::vector<RBTreeRank<uint32, RankData4Player*>> m_rank4Player;
	std::unordered_map<uint32, RankData4Player*> m_rankData4Player;

	std::vector<RBTreeRank<uint32, RankData4Guild*>> m_rank4Guild;
	std::unordered_map<uint32, RankData4Guild*> m_rankData4Guild;
};

#define sRankMgr (*RankMgr::instance())
